package com.example.demofdfs.example.map;

import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

/**
 * <p> 以单链表的形式实现(键-值)对
 * <p> put 的时间规模为 O(1), get remove set 的时间规模的最坏时为 O(n)
 * <p> 这个链表不支持 往后遍历, 不同于hash 表的是它不需要扩容也没有容量的限制,内存利用率非常高而且省内存.在内存紧缺的情况下非常有好处.
 * <p> 
 * @author chenyq
 * @date 2019-01-01
 * @email 806512500@qq.com
 * 
 * @param <K>
 * @param <V>
 */
public class LinkedMap<K, V> implements Map<K, V>, Cloneable, Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 8623363011603830634L;
	
	/**
	 * 头节点
	 */
	Node<K, V> first;
	/**
	 * 尾节点, 尾节点必须符合 (next == null)
	 */
	Node<K, V> last;
	/**
	 * 映射表的数量
	 */
	int size;
	/**
	 * 映射的结构被修改过的计数器
	 */
	int modCount;
	/**
	 * Node 键-值 对 的视图
	 */
	Set<Entry<K, V>> entrySet;
	/**
	 * key 键的视图
	 */
	Set<K> keySet;
	/**
	 * value 值的视图
	 */
	Collection<V> values;
	
	public LinkedMap() {
		
	}
	
	public LinkedMap(Map<K, V> m) {
		putAll(m);
	}
	
	@Override
	public int size() {
		return size;
	}

	@Override
	public boolean isEmpty() {
		return size == 0;
	}

	@Override
	public boolean containsKey(Object key) {
		return get(key) != null;
	}

	@Override
	public boolean containsValue(Object value) {
		Node<K, V> f = first;
		while(f != null) {
			if(f.getValue().equals(value))
				return true;
			f = f.next;
		}
		return false;
	}

	@Override
	public V get(Object key) {
		Node<K, V> n;
		return (n= node(key)) == null ? null : n.getValue();
	}

	@Override
	public V put(K key, V value) {
		if (key == null || value == null) {
			throw new NullPointerException();
		}
		return add(key, value);
	}
	
	V add(K k, V v) {
		Node<K, V> n = node(k);
		if (n != null) {
			return n.setValue(v);
		}
		modCount++;
		linklast(new Node<>(k, v));
		return null;
	}
	
	Node<K, V> node(Object key) {
		Node<K, V> node = first;
		while (node != null) {
			K k = node.getKey();
			if(key == k || (key != null && key.equals(k))) {
				return node;
			}
			node = node.next;
		}
		return null;
	}
	
	void linklast(Node<K, V> n) {
		Node<K, V> l = last;
		last = n;
		
		if (first == null) {
			first = n;
		} else {
			l.next = n;
		}
		size++;
	}

	@Override
	public V remove(Object key) {
		Node<K, V> n;
		return (n = unlink(key)) == null ? null : n.getValue();
	}
	
	Node<K, V> unlink(Object key) {
		Node<K, V> prev = first;
		Node<K, V> e = prev;
		while(e != null) {
			Node<K, V> next = e.next;
			K k;
			if ((k = e.getKey()) == key || (k != null && k.equals(key))) {
				size--;
				modCount++;
				if (e == first) {
					first = next;
				} else {
					prev.next = next;
				}
				return e;
			}
			prev = e;
			e = next;
		}
		
		return e;
	}

	@Override
	public void putAll(Map<? extends K, ? extends V> m) {
		if (m == null) {
			throw new NullPointerException();
		}
		modCount++;
		for(Entry<? extends K, ? extends V> entry : m.entrySet()) {
			add(entry.getKey(), entry.getValue());
		}
	}

	@Override
	public void clear() {
		Node<K, V> n, f = first;
		first = null;
		last = null;
		while(f != null) {
			n = f.next;
			f.next = null;
			f = n;
		}
		size = 0;
		modCount++;
	}

	@Override
	public Set<K> keySet() {
		return keySet == null ? (keySet =  new KeySet()) : keySet;
	}
	
	/**
	 * 这是一个只支持包含返回所有 key 的迭代器的Set视图
	 */
	class KeySet extends AbstractSet<K> {

		@Override
		public Iterator<K> iterator() {
			return new KeySetIterator();
		}

		@Override
		public int size() {
			return size;
		}
		
	}

	@Override
	public Collection<V> values() {
		return values == null ? (values = new ValueCollection()) : values;
	}
	/**
	 * 返回所有 value 的collection 的视图
	 */
	class ValueCollection extends AbstractCollection<V> {

		@Override
		public Iterator<V> iterator() {
			return new ValueSetIterator();
		}

		@Override
		public int size() {
			return size;
		}
		
	}

	@Override
	public Set<Entry<K, V>> entrySet() {
		return entrySet == null ? (entrySet = new EntrySet()) : entrySet;
	}
	/**
	 * 返回包含所有 键值对的Set 集合视图
	 *
	 */
	class EntrySet extends AbstractSet<Entry<K, V>> {

		@Override
		public Iterator<Entry<K, V>> iterator() {
			return new EntrySetIterator();
		}

		@Override
		public int size() {
			return LinkedMap.this.size;
		}

		@Override
		public String toString() {
			return "EntrySet []";
		}
	}
	
	
	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	/**
	 * 
	 * 这是一个迭代器, 
	 * @param <E>
	 */
	abstract class LinkedIterator<E> implements Iterator<E> {
		/**
		 * 下一个元素的所引
		 */
		int index;
		/**
		 * 下一个元素的指针
		 */
		Node<K, V> next;
		/**
		 * 并发修改的计数器
		 */
		int expectedModCount;
		
		Node<K, V> current;
		
		public LinkedIterator() {
			expectedModCount = modCount;
			next = first;
		}
		
		@Override
		public boolean hasNext() {
			return index < size;
		}

		Entry<K, V> nextEntry() {
			checkModCount();
			if (next == null) {
				throw new NoSuchElementException();
			}
			current = next;
			next = next.next;
			index++;
			return current;
		}
		
		void checkModCount() {
			if (expectedModCount != modCount) {
				throw new ConcurrentModificationException();
			}
		}
		
		@Override
		public void remove() {
			checkModCount();
			LinkedMap.this.unlink(current.key);
			expectedModCount = modCount;
			index--;
		}
	}

	class EntrySetIterator extends LinkedIterator<Entry<K, V>> {

		@Override
		public Entry<K, V> next() {
			return nextEntry();
		}
	}
	class KeySetIterator extends LinkedIterator<K> {
		
		@Override
		public K next() {
			return nextEntry().getKey();
		}
		
	}
	class ValueSetIterator extends LinkedIterator<V> {
		
		@Override
		public V next() {
			return nextEntry().getValue();
		}
		
	}
	
	
	@Override
	public String toString() {
		if (size == 0) {
			return "[]";
		}
		StringBuilder sb = new StringBuilder();
		Node<K, V> n = first;
		do {
			sb.append(n.getKey()).append('=').append(n.getValue()).append(',').append(' ');
		} while ((n = n.next) != null);
		int len = sb.length();
		
		return sb.delete(len - 2, len).append(']').toString();
	}



	/**
	 * 
	 * 这个是用于存储键值对的节点, 即链表.是单链表, 只能往前迭代.
	 * @param <K>
	 * @param <V>
	 */
	static class Node<K, V> implements Map.Entry<K, V>, Serializable {

		/**
		 * 
		 */
		private static final long serialVersionUID = 8356467749770808672L;
		
		K key;
		V value;
		Node<K, V> next;
		
		public Node(K key, V value) {
			this.key = key;
			this.value = value;
		}

		@Override
		public K getKey() {
			return key;
		}

		@Override
		public V getValue() {
			return value;
		}

		@Override
		public V setValue(V value) {
			V oldValue = value;
			this.value = value;
			return oldValue;
		}

		@Override
		public String toString() {
			return key + "=" + value;
		}
		
		
	}
}
